package com.gking.centerSystem.AOP;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gking.centerSystem.common.BaseContext;
import com.gking.centerSystem.entity.User;
import com.gking.centerSystem.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.mindrot.jbcrypt.BCrypt;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


@Slf4j
@Primary // 确保这个切面优先被使用
@Component
public class DesensitizeDataAspectService extends DesensitizeDataAspect {

    @Resource
    private UserMapper userMapper;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private HttpServletRequest request;

    // 脱敏认证
    private static final String Data_Desensitize_Verify = "Data:Desensitize:Verify:user_";
    // 脱敏认证持续时间
    private static final long Data_Desensitize_Verify_TTL = 30L;


    @Override
    public long verify(String password) {
        String userId = BaseContext.getCurrentId();

        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getId, userId);
        lambdaQueryWrapper.eq(User::getEnable, 0);
        User user = userMapper.selectOne(lambdaQueryWrapper);

        // 检查密码是否正确，密码错误则返回
        boolean passwordMatch = BCrypt.checkpw(password, user.getPassword());
        if (!passwordMatch) return 0L;

        // 设置脱敏校验状态
        return this.setDataVerifyStatus();
    }

    @Override
    public long setDataVerifyStatus() {
        String loginUser = BaseContext.getCurrentId() + BaseContext.getLoginVerifyCode();
        String key = Data_Desensitize_Verify + loginUser;
        // 确保 TTL 是以小时为单位的 long 类型
        long ttlInMillis = TimeUnit.MINUTES.toMillis(Data_Desensitize_Verify_TTL);

        // 设置键值对及其过期时间
        stringRedisTemplate.opsForValue().set(key, "true", Data_Desensitize_Verify_TTL, TimeUnit.MINUTES);

        // 计算过期时间戳：当前时间 + TTL(毫秒)
        long expireAtTimestamp = System.currentTimeMillis() + ttlInMillis;

        return expireAtTimestamp;
    }

    @Override
    public boolean getDataVerifyStatus() {
        String loginUser = BaseContext.getCurrentId() + BaseContext.getLoginVerifyCode();
        String s = stringRedisTemplate.opsForValue().get(Data_Desensitize_Verify + loginUser);

        if (s == null) return false;
        if (Objects.equals(s, "true")) return true;
        else return false;
    }

    @Override
    public long getDataVerifyExpireTime() {
        String loginUser = BaseContext.getCurrentId() + BaseContext.getLoginVerifyCode();
        String key = Data_Desensitize_Verify + loginUser;

        // 如果使用此方法，请注意处理可能的null返回值
        long ttlMillis = stringRedisTemplate.getExpire(key, TimeUnit.MILLISECONDS);
        long currentTimestampMillis = System.currentTimeMillis();

        if (ttlMillis > 0) return ttlMillis + currentTimestampMillis;

        return 0L;
    }

    @Override
    public void refreshDataVerifyStatus() {
        String loginUser = BaseContext.getCurrentId() + BaseContext.getLoginVerifyCode();
        String key = Data_Desensitize_Verify + loginUser;
        String s = stringRedisTemplate.opsForValue().get(Data_Desensitize_Verify + loginUser);
        if (s == null) return;

        // 确保 TTL 是以小时为单位的 long 类型
        long ttlInMillis = TimeUnit.MINUTES.toMillis(Data_Desensitize_Verify_TTL);
        // 计算过期时间戳：当前时间 + TTL(毫秒)
        long expireAtTimestamp = System.currentTimeMillis() + ttlInMillis;

        if (Objects.equals(s, "true")) {
            stringRedisTemplate.opsForValue().set(key, "true", Data_Desensitize_Verify_TTL, TimeUnit.MINUTES);
            String requestURI = request.getRequestURI();
            log.info("刷新脱敏认证时间戳 ： {}  URI : {} ", expireAtTimestamp, requestURI);
        }
    }


}
